GitHub Actions is a CI/CD (Continuous Integration / Continuous Delivery) platform integrated directly into GitHub. This article walks you through building a CI/CD pipeline in 30 minutes, step by step.

💡 Key Takeaway

If you have a GitHub repository, you can start CI/CD at no additional cost. Public repos get unlimited build time; private repos get 2,000 minutes/month free.

1. What is GitHub Actions?

GitHub Actions automates the process of "testing, building, and deploying code when you push."

Key Terminology

  • Workflow: The entire automation process, defined in YAML
  • Job: An execution unit within a workflow — can run in parallel or sequentially
  • Step: An individual command or Action within a job
  • Action: A reusable component, shared via the Marketplace
  • Runner: The server that executes workflows
Ad

2. Workflow Basics

Workflows are placed as YAML files in the .github/workflows/ directory.

# .github/workflows/ci.yml
name: CI Pipeline

# Trigger: on push or PR to main
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18, 20, 22]

    steps:
      # 1. Checkout code
      - uses: actions/checkout@v4

      # 2. Set up Node.js
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      # 3. Install dependencies
      - run: npm ci

      # 4. Run lint
      - run: npm run lint

      # 5. Run tests
      - run: npm test

      # 6. Verify build
      - run: npm run build
✅ Pro Tip

Using strategy.matrix enables parallel testing across multiple Node.js versions — invaluable for ensuring compatibility.

3. Implementing Test Automation

A practical workflow that runs tests automatically when a PR is created and comments results on the PR.

# .github/workflows/test-report.yml
name: Test with Coverage Report

on:
  pull_request:
    branches: [ main ]

jobs:
  test-coverage:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci
      - run: npm test -- --coverage --coverageReporters=text

      # Comment coverage on PR
      - name: Comment Coverage on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const coverage = '✅ Tests passed!';
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: coverage
            })
Ad

4. Setting Up Auto-Deploy

A workflow that auto-deploys to production when code is merged to main.

# .github/workflows/deploy.yml
name: Deploy to Production

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    needs: test

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      # Deploy to GitHub Pages
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

      # Notification
      - name: Notify on Success
        if: success()
        run: |
          echo "✅ Deploy complete!"

5. Practical Tips

Speed Up with Caching

# npm dependency caching (automatic)
- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: 'npm'  # This alone enables caching

Managing Secrets

Store API keys and passwords in GitHub Secrets for safe access from workflows.

  1. Go to Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Enter name and value, then save
  4. Reference in workflows with ${{ secrets.SECRET_NAME }}
⚠️ Security Warning

Never print secrets to logs. GitHub Actions masks them automatically, but they can leak through indirect means like Base64 encoding.

Summary

With GitHub Actions, you can build the following CI/CD pipeline in 30 minutes:

  1. On PR creation: Auto-test + coverage report
  2. On merge: Auto-build + auto-deploy
  3. On error: Slack/email notification

Start small and expand your workflows gradually.